mouse pointerのいる文字を取得するテスト
特定の座標からscrapboxの文字を取得するテスト
実装
検索する座標値として、mouse pointerの座標を使う
行の取得
文字の取得
span[class^="c-"]だけ抜き出して検索する
code:test.js
document.addEventListener('mousemove',e=>{
const left = e.pageX;
const top = e.pageY - window.scrollY;
const rect = line.getBoundingClientRect();
return rect.top <= top && top < rect.bottom
//&& rect.left <= left && left < rect.right; // Y座標だけ範囲内であればいい
});
if (!line) return {error:'out of range'};
const chars = [...line.querySelectorAll('spanclass^="c-"')]; const lineHeight = parseInt(window.getComputedStyle(scrapboxDOM.lines).lineHeight);
const lineTop = line.getBoundingClientRect().top;
const breakNum = Math.floor((top - lineTop) / lineHeight); // aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa折返しされた行で何行目から文字を検索するのか
// 指定した座標を含む表示上の行内に含まれる文字のリスト
const charsInTargetVisibleLine = line.getBoundingClientRect().height > lineHeight ?
chars.filter(char => {
const charTop = char.getBoundingClientRect().top;
return lineTop + breakNum * lineHeight <= charTop
&& charTop < lineTop + (breakNum + 1) * lineHeight;
}) :
chars;
// 先に範囲外かどうかを調べる
if (charsInTargetVisibleLine0.getBoundingClientRect()?.left > left) { console.log({
breakNum,
char: 'Head',
chars,
line,
});
return;
}
console.log({
breakNum,
char: 'LF',
chars,
line,
});
return;
}
// x成分から文字を検索する
const char = charsInTargetVisibleLine
.find(char => {
const rect = char.getBoundingClientRect();
return rect.left <= left && left < rect.right;
↑ここでrect.bottomとかを使うと、文字の無い隙間にmouse pointerが来たときに文字を取得できない
代わりに行のborder入りの幅を使う
折返しがあると一行あたりの高さにならない
代わりに#compute-lineを使う compute-lineも幅が一定でない
隙間対策のために、二段階で検索する
1回目はx成分のみで検索する
これで複数文字が検出されたときは、更にy成分で絞り込みをかける
折り返し前の位置が空欄で、折り返し後にしか文字がない領域で誤判定してしまう
全部の場合で行数を計算するようにしよう。
行末判定がうまく行かないな
行頭の扱い
先頭文字より左側にあったらHeadを返す
行末の扱い
末尾より右側にあったらLFを返す
code:test.js
});
console.log({
breakNum,
char,
chars,
line,
})
})